package linkedlist;

import Exceptions.BadDataExcepiton;
import Exceptions.EmptyLinkedListException;
import Exceptions.OutOfLinkedListException;

/**
 * 
 * @author Nikola
 * 
 * 
 */
public class LinkedList implements ILinkedList {
	private static final int FIRST_INDEX = 1;
	private Node start;
	private int size;

	/**
	 * Adds a new node in the beginning, filling it with given data.
	 * 
	 * @param index
	 *            - the index of the element
	 * @return the element's data at that position
	 * @param data
	 *            - data to be added at the beginning
	 * @throws BadDataExcepiton
	 *             - when null is passed
	 * @throws
	 */
	public void add(Object data) throws BadDataExcepiton,
			EmptyLinkedListException {
		if (start == null) {
			start = new Node(data, start);
			size++;
			throw new EmptyLinkedListException("The linked list is empty!");

		} else {
			// create a new node with given data and start as a next
			Node newNode = new Node(data, start);
			start = newNode;
		}
		size++;
	}

	public Object get(int index) throws OutOfLinkedListException,
			EmptyLinkedListException {
		Node current = start;
		if (start == null)
			throw new OutOfLinkedListException("Empty LinkedList !");
		if (index < 0) {
			throw new OutOfLinkedListException("Negative index !");
		}
		for (int i = 0; i < index; i++) {
			if (current == null)
				throw new OutOfLinkedListException("No such element!");
			current = current.getNext();
		}
		return current.getData();
	}

	public int getSize() {
		return size;
	}

	@Override
	public void remove(int index) {
		// TODO Auto-generated method stub
		
	}

	// LinkedList() {
	// firstNode = null;
	// }
	//
	// public void add(Object data) {
	// Node newNode;
	// try{
	// newNode = new Node(data);
	// }
	// catch (BadDataExcepiton e){
	// System.out.println();
	// }
	// if (firstNode == null)
	// firstNode = new Node(data);
	// else
	// returnLastNode(firstNode).setNode(newNode);
	// }
	//
	// public void insertAt(int index, Object data) {
	// // check case when node is null !!!
	// Node previousNode = returnNodeAtIndex(firstNode, index, FIRST_INDEX);
	// Node newNode = new Node(data);
	// newNode.setNode(previousNode.getNode());
	// previousNode.setNode(newNode);
	// }
	//
	// public void remove(int index) {
	// // null pointer
	// Node previousNode = returnNodeAtIndex(firstNode, index, FIRST_INDEX);
	// previousNode.setNode(previousNode.getNode().getNode());
	// }
	//
	// public Object get(int index) {
	// // null pointer?
	// return returnNodeAtIndex(firstNode, index, FIRST_INDEX).getData();
	// }
	//
	// private Node returnNodeAtIndex(Node current, int endIndex, int
	// currentIndex) {
	// if (currentIndex == endIndex - 1)
	// return current;
	// if(currentIndex>endIndex)
	// currentIndex++;
	// return returnNodeAtIndex(current.getNode(), endIndex, currentIndex);
	// }
	//
	// private Node returnLastNode(Node current) {
	// // if current == null ?
	// if (current.getNode() == null)
	// return current;
	// return current.getNode();
	// }
}
